package com.siecom.module;

import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;

import com.siecom.constconfig.ConstDefine;
import com.siecom.constconfig.ErrorDefine;
import com.siecom.tool.ByteTool;
import com.siecom.tool.LogUtil;
import com.siecom.transport.serialport.SerialHelper;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.security.InvalidParameterException;

import android_serialport_api.SerialPort;

/**
 * Created by zhq on 2016/8/4.
 */
public class FwUpdateModule {

    private static final String TAG = "FwUpdateModule";

    public DownloadThread downloadThread = null;
    public int iFileLen = 0;
    public boolean openFileFlag = false;
    public int openBinFileFlag = 0;
    public byte[] binBuffer = null;
    public int availableLen = 0;
    private int[] data = new int[100];
    FinancialModule financialModule = FinancialModule.getInstance();
    DeviceCallback callback;
    boolean isOnMain;

    SerialControl mSerialControl;

    public void setCallback(DeviceCallback callback, boolean isOnMain) {

        this.callback = callback;
        this.isOnMain = isOnMain;
    }


    public int readFile(String fileName) throws IOException {
        mSerialControl = new SerialControl();
        try {
            FileInputStream fin = new FileInputStream(fileName);
            availableLen = fin.available();
            //Log.i(tag, "availableLen = " + availableLen);

            binBuffer = new byte[availableLen];
            iFileLen = fin.read(binBuffer);
            if (iFileLen != availableLen) {
                fin.close();
                return -1;
            }

            Log.i("readFile", "iFileLen: " + iFileLen);
            fin.close();
            openBinFileFlag = 1;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return 0;
    }

    public void beginDownLoad(DeviceCallback callback){
        if(Build.MODEL.equals("US811"))
            mSerialControl = new SerialControl("/dev/ttyHSL0");
        else if(Build.MODEL.equals("US812"))
            mSerialControl = new SerialControl("/dev/ttyHSL0");
        else mSerialControl = new SerialControl();
        OpenComPort(mSerialControl);
        //mSerialControl.createRecvThread();

        if (null != downloadThread && !downloadThread.isThreadFinished()) {
            Log.e("error", "Thread is still running");
            return;
        }
        downloadThread = new DownloadThread(callback);
        downloadThread.start();
    }

    public void mcuReset(){
        String device_model = Build.MODEL;
        Log.d("log",device_model);
        Log.d("log",Build.DISPLAY);
        if(device_model.equals("MF-2352")) {

            PowerOnFg(0);
            try {
                Thread.sleep(500);//延时50ms
            } catch (InterruptedException e){
                e.printStackTrace();
            }
            PowerOnFg(1);
        }
        else if(device_model.equals("rk3188")){
            // com.siecom.nativelibs.rkGpioControlNative.ControlGpio(com.siecom.nativelibs.rkGpioControlNative.RK30_PIN0_PA2, 0);
            try {
                Thread.sleep(500);//延时50ms
            } catch (InterruptedException e){
                e.printStackTrace();
            }
            // com.siecom.nativelibs.rkGpioControlNative.ControlGpio(com.siecom.nativelibs.rkGpioControlNative.RK30_PIN0_PA2, 1);
        }
        else
            PowerOnReader(0);
        try {
            Thread.sleep(500);//延时50ms
        } catch (InterruptedException e){
            e.printStackTrace();
        }
        PowerOnReader(1);
    }

    public void PowerOnFg(int flag)
    {
        try
        {
            File file = new File("/sys/class/gpio/gpio928/value");
            FileWriter localFileWriter = new FileWriter(file);
            if(flag==0)
                localFileWriter.write("1");
            else if(flag==1)
                localFileWriter.write("0");
            localFileWriter.close();
            file = new File("/sys/class/gpio/gpio922/value");

            localFileWriter = new FileWriter(file);
            if(flag==1)
                localFileWriter.write("1");
            else if(flag==0)
                localFileWriter.write("0");
            localFileWriter.close();

            file = new File("/sys/class/gpio/gpio920/value");

            localFileWriter = new FileWriter(file);
            if(flag==1)
                localFileWriter.write("1");
            else if(flag==0)
                localFileWriter.write("0");
            localFileWriter.close();

            file = new File("/sys/class/gpio/gpio919/value");

            localFileWriter = new FileWriter(file);
            if(flag==0)
                localFileWriter.write("1");
            else if(flag==1)
                localFileWriter.write("0");
            localFileWriter.close();


            return;
        }
        catch (IOException localIOException)
        {
            localIOException.printStackTrace();
        }
    }

    public void PowerOnReader(int flag)
    {
//        if(Build.MODEL.equals("tb8788p1_64_bsp")){
//            gpio_A317(flag);
//            return ;
//        }
        if(Build.MODEL.equals("CJ-P1")){
            gpio_control(99,flag);
            return ;
        }
        if(Build.MODEL.equals("msm8937 for arm64")||Build.MODEL.equals("W-500A")||Build.MODEL.equals("US830")){
            gpio_control(93,flag);
            gpio_control(46,flag);
            return ;
        }
        if(Build.MODEL.equals("A108Plus")){
            gpio_control(93,flag);
            return ;
        }
        if(Build.MODEL.equals("US835")){
            gpio_control(93,flag);
            return ;
        }
        if(Build.MODEL.equals("PAD Pro")||Build.MODEL.equals("US820")||Build.MODEL.equals("US819")||Build.MODEL.equals("HJ-TM1800-10")||Build.MODEL.equals("MX737")||Build.MODEL.equals("US821")||Build.MODEL.equals("US823")){
            gpio_control(93,flag);
            // gpio_control(46,flag);
            return ;
        }
        if(Build.MODEL.equals("US817")||Build.MODEL.equals("PAD")){
            gpio_control(97,flag);
            return ;
        }
        if(Build.MODEL.equals("US811")){
            gpio_control(85,flag);
            gpio_control(44,flag);

            return ;
        }
        if(Build.MODEL.equals("US812")){
            gpio_control(85,flag);
            return ;
        }
        if(Build.MODEL.equals("US833")){
            gpio_control(66,flag);
            return ;
        }
        if(Build.MODEL.equals("US811")){
            gpio_control(44,flag);
            return ;
        }

        if(Build.MODEL.equals("Z90")){
            gpio_control(1009,flag);
            /*
            try {
                File file = new File("/dev/telpoio");
                FileWriter localFileWriter = new FileWriter(file);
                if (flag == 1)
                    localFileWriter.write("1");
                else if (flag == 0)
                    localFileWriter.write("0");
                localFileWriter.close();
            }
            catch (IOException localIOException)
            {
                localIOException.printStackTrace();
                return ;
            }*/
            return ;
        }
        if(Build.MODEL.equals("ESAPOS E6")){
            try
            {
                Log.d("log","NFC_PowerState control");
                File file = new File("/proc/aeon_sub2");
                if(file.exists()==false)
                {
                    file = new File("/sys/devices/platform/battery/NFC_PowerState");

                    FileWriter localFileWriter = new FileWriter(file);
                    if(flag==1)
                        localFileWriter.write("2");
                    else if(flag==0)
                        localFileWriter.write("0");
                    localFileWriter.close();
                }
                else {
                    FileWriter localFileWriter = new FileWriter(file);
                    if(flag==1)
                        localFileWriter.write("1");
                    else if(flag==0)
                        localFileWriter.write("0");
                    localFileWriter.close();
                }
            }
            catch (IOException localIOException)
            {
                localIOException.printStackTrace();
                return ;
            }
            return ;
        }
        try
        {
            //FileWriter localFileWriter = new FileWriter(new File("/sys/devices/platform/finance_pos/finance_pos_ctrl"));
            File file = new File("/sys/kernel/wii-peripheral/mcu_pwr");
            if(file.exists()==false) file = new File("/sys/devices/mcu.15/mcu_power");
            if(file.exists()==false) file = new File("/sys/devices/platform/finance_pos/finance_pos_ctrl");
            if(file.exists()==false) file = new File("/sys/class/gpio/gpio1009/value");
            //if(file.exists()==false) file = new File("/sys/class/scan/scan/scan");



            if(file.exists()==false) file = new File("/sys/class/gpio/gpio93/value");

            //file.delete();

            FileWriter localFileWriter = new FileWriter(file);
            if(flag==1)
                localFileWriter.write("1");//1
            else if(flag==0)
                localFileWriter.write("0");
            localFileWriter.close();




            /*
            FileReader read = new FileReader(file);
            char[] ch = new char[1];
            read.read(ch);


            //Toast.makeText(MainActivity.this, "rs:" + new String(ch), Toast.LENGTH_SHORT).show();
            file = new File("/sys/class/gpio/export");
            localFileWriter = new FileWriter(file);
            localFileWriter.write("125");
            localFileWriter.close();
            file = new File("/sys/class/gpio/gpio125/direction");
            localFileWriter = new FileWriter(file);
            localFileWriter.write("out");
            localFileWriter.close();
            file = new File("/sys/class/gpio/gpio125/value");
            localFileWriter = new FileWriter(file);
            localFileWriter.write("1");
            localFileWriter.close();
            if(file.exists()==false) file = new File("/sys/class/gpio/gpio125/value");

            read = new FileReader(file);
            read.read(ch);
            Toast.makeText(MainActivity.this, "rs:" + new String(ch), Toast.LENGTH_SHORT).show();
            */
            return;
        }
        catch (IOException localIOException)
        {
            localIOException.printStackTrace();
        }
    }

    private void gpio_control(int gpio,int mode){
        try
        {
            String file_name = new String("/sys/class/gpiocontrol/gpiocontrol/gpiocontrol"+gpio);
            File file = new File(file_name);
            if(file.exists()==false){
                file_name = new String("/sys/class/gpio/gpio"+gpio+"/value");
                file = new File(file_name);
            }
            if(file.exists()==false) return;
            FileWriter localFileWriter = new FileWriter(file);
            if(mode==1)
                localFileWriter.write("1");
            else if(mode==0)
                localFileWriter.write("0");
            localFileWriter.close();
        }
        catch (IOException localIOException)
        {
            localIOException.printStackTrace();
        }
    }

    private class SerialControl extends SerialHelper {

        public SerialControl(){
        }
        public SerialControl(String sPort){
            super(sPort);
        }
        public SerialControl(String sPort,int iBaudRate){
            super(sPort,iBaudRate);
        }
    }
    private void OpenComPort(SerialHelper ComPort){
        try
        {
            ComPort.open();
        } catch (SecurityException e) {
            ShowMessage("打开串口失败:没有串口读/写权限!");
        } catch (IOException e) {
            ShowMessage("打开串口失败:未知错误!");
        } catch (InvalidParameterException e) {
            ShowMessage("打开串口失败:参数错误!");
        }
    }
    private void CloseComPort(SerialHelper ComPort){
        if (ComPort!=null){
            ComPort.close();
        }
    }
    private void ShowMessage(String sMsg){
        Log.e("Loadtools",sMsg);
    }

    private class DownloadThread  extends Thread
    {
        private boolean m_bThreadFinished = false;
        private boolean m_bThreadStoped = false;

        int iRet = 0, totalPacket;
        byte i;
        byte data[] = new byte[2048];

        public boolean isThreadFinished(){
            return m_bThreadFinished;
        }
        public boolean isThreadStoped(){return m_bThreadStoped;}
        public void StopThread(){
            m_bThreadStoped = true;
        }
        public DeviceCallback callback;

        DownloadThread(DeviceCallback callback){
            this.callback = callback;
            this.setPriority(Thread.MIN_PRIORITY);
        }

        @Override
        public void run(){

            //' SerialPort.DownloadBoot("/sdcard/scp_packets/packet.list");

            m_bThreadFinished = false;
//			Log.e("", "1111111111");
            if(openBinFileFlag == 0){
                //SendMsg("Open a bin file first, please !", 0);
                m_bThreadFinished = true;
                return;
            }

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

//            SendMsg("HandShaking ...", SHOWMSG);
            byte[] abySendBuff = new byte[1];
            abySendBuff[0] = '0';
            //mSerialControl.send(abySendBuff);

            abySendBuff = new byte[8];
            abySendBuff[0] = (byte)0x02;
            abySendBuff[1] = (byte)0xD1;
            abySendBuff[2] = (byte)0x11;
            abySendBuff[3] = (byte)0x00;
            abySendBuff[4] = (byte)0x01;
            abySendBuff[5] = (byte)0x00;
            abySendBuff[6] = (byte)0xc3;
            abySendBuff[7] = (byte)0x91;
            mSerialControl.send(abySendBuff);


            try
            {
                Thread.sleep(100);
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            abySendBuff[0] = (byte)0x02;
            abySendBuff[1] = (byte)0xb9;
            abySendBuff[2] = (byte)0x09;
            abySendBuff[3] = (byte)0x00;
            abySendBuff[4] = (byte)0x00;
            abySendBuff[5] = (byte)0x9c;
            abySendBuff[6] = (byte)0x37;
            mSerialControl.send(abySendBuff);

            iRet = HandShake();
            if(iRet == 0){
                DownloadFile( callback);
            }

            CloseComPort(mSerialControl);
            m_bThreadFinished = true;
        }
    }

    public int DownloadFile(DeviceCallback callback){
        int byteOffset = 0;
        int dwCurrentLen = 0;
        int iErrorCount = 0;
        int wPacketLen = 0;
        int iReadLen = 0;
        short iSendPacketLen = 0;
        int iRet;
        byte [] abyTemp = new byte[5000];
        byte [] abyCompress = new byte[50];

        short pwPacketetLen[] = new short[1];

        dwCurrentLen = 0;
        iErrorCount = 0;
        Log.d("DownloadFile", "iFileLen = " + iFileLen);
//        ShowBar(0, SHOWBAR);
        Bundle bundle = new Bundle();
        while (true){
            if (dwCurrentLen >= iFileLen)
            {
                break;
            }

            int progress = (dwCurrentLen*100)/iFileLen;
            LogUtil.e(TAG,"Progress : " + progress + "%");
            bundle.putInt("data",progress);
            callback.onSuccess(bundle);
//            SendMsg("Progress : " + progress + "%", 0);
//            ShowBar(progress, SHOWPROGRESS);

            wPacketLen = 512;
            if ((dwCurrentLen+512) > iFileLen){
                wPacketLen = (iFileLen - dwCurrentLen);
            }

            byteOffset += iReadLen;
            System.arraycopy(binBuffer, byteOffset, abyTemp, 5, wPacketLen);

            iReadLen = wPacketLen;

            if (iReadLen > 0)
            {
                abyTemp[0] = 0;
                abyTemp[1] = (byte)((iReadLen/65536)%256);
                abyTemp[2] = (byte)((iReadLen%65536)/256);
                abyTemp[3] = (byte)(iReadLen%256);
                abyTemp[4] = 0;  // data no zip
                iSendPacketLen = (short)(iReadLen+5);
                iErrorCount = 0;

                while(true){
                    iRet = sendPackage(abyTemp, iSendPacketLen, (byte)0xb0);
                    Log.e("", "Lib_SendPacket iRet = " + iRet);
                    if(iRet != 0){
                        Log.e("", "Lib_SendPacket iRet = " + iRet);
                        return 10;
                    }
                    pwPacketetLen[0] = 0;

                    iRet = recvPacket(abyCompress, pwPacketetLen, 5000);
                    if ((0==iRet) && (0x0B==abyCompress[5])){

                        break;
                    }
                    iErrorCount++;
                    if (iErrorCount > 0){
                        if (-1 == iRet){
//                            SendMsg("Receive timeout!", 0);
                        }
                        else{
//                            SendMsg("Receive failed!", 0);
                        }
                        return 5;
                    }
                }
                dwCurrentLen += iReadLen;
            }
            else{
                break;
            }
        }

        pwPacketetLen[0] = 0;

        sendPackage(abyTemp, (short)0, (byte) 0xb1);
        iRet = recvPacket(abyCompress, pwPacketetLen, 5000);

        sendPackage(abyTemp, (short) 0, (byte) 0xD2);

        SendMsg("DownLoad Success !", 0);
        callback.onCompleted(bundle);
//        ShowBar(100, SHOWPROGRESS);
//
//        ShowBar(0, SHOWBAR);
        return 0;
    }

    public  int sendPackage(byte[] send, short length,byte cmd)  {

        byte[] sendBuffer=new byte[length+8];
        byte[] crcdata=new byte[length+3];
        byte[] crc=new byte[4];

        sendBuffer[0] = 0x02;

        sendBuffer[1] = cmd;
        sendBuffer[2] = (byte)(length/256);
        sendBuffer[3] = (byte)(length%256);


        System.arraycopy(send,0,sendBuffer, 4, length);
        System.arraycopy(sendBuffer, 1, crcdata, 0, length + 3);

        mSerialControl.Quick32Crc(crcdata, length + 3, crc);
        //QuickCrc32(crcdata, length + 3, crc);

        System.arraycopy(crc,0,sendBuffer,length+4,4);

        //java.util.zip.CRC32();
        mSerialControl.send(sendBuffer);

        return  0 ;
    }

    public int recvPacket(byte[] pbyRecvData, short[] pwPacketetLen, int dwTimeoutMs) {
        int byRet;
        byte[] abyCrc32=new byte[4];
        int i;
        byte[] ch=new byte[1];
        short wPacketLen = 0;
        int dwBegintick, dwCurtick;

        //Log.i("RecvPacket", "begin");
        for(i=0;i<dwTimeoutMs;i+=1000)
        {
            byRet = mSerialControl.Pop(ch, 1000);
            if ((0==byRet) && (0x02==ch[0]))
            {
                pbyRecvData[0] = ch[0];
                break;
            }
            try {
                Thread.sleep(10);//延时50ms
            } catch (InterruptedException e){
                e.printStackTrace();
            }
        }
        if(i>=dwTimeoutMs) {
            Log.i("RecvPacket","timeout1");
            return 104;

        }
        for(i=1;i<4;i++){
            byRet = mSerialControl.Pop(ch,1000); // timeout = 100ms
            if (0 != byRet)
            {
                Log.i("RecvPacket","timeout2");
                return 101;
            }
            pbyRecvData[i] = ch[0];
        }
        wPacketLen = (short) (pbyRecvData[2]*256 + pbyRecvData[3]);
        pwPacketetLen[0] = (short) (wPacketLen + 8);
        if (wPacketLen > 520)
        {
            Log.i("RecvPacket","PackeLen error");
            return 103;
        }
        for (i=4; i<wPacketLen+8; i++)
        {
            byRet = mSerialControl.Pop(ch, 1000);
            if (0 != byRet)
            {
                Log.i("RecvPacket","timeout3");
                return 101;
            }
            pbyRecvData[i] = ch[0];
        }
        //Log.i("RecvPacket", "" + ByteUtil.bytearrayToHexString(pbyRecvData, wPacketLen+8));

	     /*
	     QuickCrc32(&pbyRecvData[1], wPacketLen+3, abyCrc32);
	     if (0 != memcmp(&pbyRecvData[wPacketLen+4],abyCrc32,4))
	     {
	         return LRC_CHECK_ERROR;
	     }*/
        return 0;
    }
    public int HandShake(){
        byte[] abyRecvBuff = new byte[1];
        byte[] abySendBuff = new byte[1];
        int iRet, i;

        SendMsg("connecting...", 0);

        i = 0;

        for(;i<10;i++)
        {
            abySendBuff[0] = 'T';

            if(downloadThread.isThreadStoped()==true) return 1;
            mSerialControl.send(abySendBuff);

            iRet = mSerialControl.Pop(abyRecvBuff, 1000);

            if(iRet==0&&abyRecvBuff[0]=='S'){
                abySendBuff[0] = 'Q';
                if(downloadThread.isThreadStoped()==true) return 1;
                mSerialControl.send(abySendBuff);
                iRet = mSerialControl.Pop(abyRecvBuff, 3000);

                if(iRet==0&&abyRecvBuff[0]=='P') break;
            }
            else i--;
        }
        if(i!=10) {
            SendMsg("Hand shack success !", 0);
            return 0;
        }
        return 1;
    }

    public void SendMsg(String msg,int i){
        LogUtil.e(TAG,msg + "----" + i);
    }







//    private class DownloadThread extends Thread {
//        private boolean m_bThreadFinished = false;
//        int iRet = 0, totalPacket;
//        byte i;
//        byte data[] = new byte[2048];
//
//        public boolean isThreadFinished() {
//            return m_bThreadFinished;
//        }
//
//        DownloadThread() {
//
//            this.setPriority(Thread.MIN_PRIORITY);
//
//        }
//
//        @Override
//        public void run() {
//            m_bThreadFinished = false;
////			Log.e("", "1111111111");
//            if (openBinFileFlag == 0) {
//                //SendMsg("Open a bin file first, please !", 0);
//                Bundle bundle = new Bundle();
//                bundle.putInt("code", ErrorDefine.FILE_ERR);
//                bundle.putString("message", "FILE_ERR!");
//                deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
//                m_bThreadFinished = true;
//                return;
//            }
//
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                // TODO Auto-generated catch block
//                e.printStackTrace();
//            }
//
//            Log.e("HandShaking ...", "------");
//            try {
//                Thread.sleep(2000);
//            } catch (InterruptedException e) {
//                // TODO Auto-generated catch block
//                e.printStackTrace();
//            }
//
//            iRet = HandShake();
//
//
//            if (iRet == 0) {
//                try {
//                    DownloadFile();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//
//            m_bThreadFinished = true;
//        }
//    }

//    public int HandShake() {
//        byte[] abyRecvBuff = new byte[1];
//        byte[] abySendBuff = new byte[1];
//        int iRet = 0, i;
//        synchronized (this) {
//            Log.e("connecting...", "0...");
//            i = 0;
//            for (; i < 10; i++) {
//                abySendBuff[0] = 'T';
//                financialModule.write(abySendBuff);
//                try {
//                    iRet = financialModule.read(abyRecvBuff, 1, 100);
//
//                    if (iRet == 0 && abyRecvBuff[0] == 'S') {
//                        abySendBuff[0] = 'Q';
//                        financialModule.write(abySendBuff);
//                        iRet = financialModule.read(abyRecvBuff, 1, 3000);
//                        if (iRet == 0 && abyRecvBuff[0] == 'P') break;
//                    } else i--;
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//            if (i != 10) {
//                Log.e("Hand shack success !", "---next");
//                return 0;
//            }
//        }
//        return 1;
//    }

    public int DownloadFile(String depreted) throws IOException {
        int byteOffset = 0;
        int dwCurrentLen = 0;
        int iErrorCount = 0;
        int wPacketLen = 0;
        int iReadLen = 0;
        short iSendPacketLen = 0;
        int iRet;
        byte[] abyTemp = new byte[5000];
        byte[] abyCompress = new byte[50];

        short pwPacketetLen[] = new short[1];

        dwCurrentLen = 0;
        iErrorCount = 0;
        Log.d("DownloadFile", "iFileLen = " + iFileLen);
        deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);
        while (true) {
            if (dwCurrentLen >= iFileLen) {
                break;
            }

            int progress = (dwCurrentLen * 100) / iFileLen;
            Log.e("Progress : ", progress + "%");

            Bundle bundle = new Bundle();
            bundle.putInt("data", progress);
            deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);

            wPacketLen = 512;
            if ((dwCurrentLen + 512) > iFileLen) {
                wPacketLen = (iFileLen - dwCurrentLen);
            }

            byteOffset += iReadLen;
            System.arraycopy(binBuffer, byteOffset, abyTemp, 5, wPacketLen);

            iReadLen = wPacketLen;

            if (iReadLen > 0) {
                abyTemp[0] = 0;
                abyTemp[1] = (byte) ((iReadLen / 65536) % 256);
                abyTemp[2] = (byte) ((iReadLen % 65536) / 256);
                abyTemp[3] = (byte) (iReadLen % 256);
                abyTemp[4] = 0;  // data no zip
                iSendPacketLen = (short) (iReadLen + 5);
                iErrorCount = 0;

                while (true) {
                    iRet = sendPackage(abyTemp, iSendPacketLen, (byte) 0xb0);
                    Log.e("", "Lib_SendPacket iRet = " + iRet);
                    if (iRet != 0) {
                        Log.e("", "Lib_SendPacket iRet = " + iRet);
                        return 10;
                    }
                    pwPacketetLen[0] = 0;
                    iRet = recvPacket(abyCompress, pwPacketetLen, 5000);
                    if ((0 == iRet) && (0x0B == abyCompress[5])) {

                        break;
                    }
                    iErrorCount++;
                    if (iErrorCount > 0) {
                        if (-1 == iRet) {
                            Log.e("Receive timeout!", "---");
                        } else {
                            Log.e("Receive failed!", "---");
                            bundle = new Bundle();
                            bundle.putInt("code", ErrorDefine.UNKNOW_ERROR);
                            bundle.putString("message", "fail update");
                            deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                        }
                        return 5;
                    }
                }
                dwCurrentLen += iReadLen;
            } else {
                break;
            }
        }

        pwPacketetLen[0] = 0;

        sendPackage(abyTemp, (short) 0, (byte) 0xb1);

        iRet = recvPacket(abyCompress, pwPacketetLen, 5000);

        sendPackage(abyTemp, (short) 0, (byte) 0xD2);

        Log.e("DownLoad Success !", "!!!");
        deliverResult(callback, DeviceInterface.Result.COMPLETED, new Bundle(), isOnMain);
        return 0;
    }

//    public int sendPackage(byte[] send, short length, byte cmd) {
//
//        byte[] sendBuffer = new byte[length + 8];
//        byte[] crcdata = new byte[length + 3];
//        byte[] crc = new byte[4];
//
//        sendBuffer[0] = 0x02;
//
//        sendBuffer[1] = cmd;
//        sendBuffer[2] = (byte) (length / 256);
//        sendBuffer[3] = (byte) (length % 256);
//
//
//        System.arraycopy(send, 0, sendBuffer, 4, length);
//        System.arraycopy(sendBuffer, 1, crcdata, 0, length + 3);
//
//        financialModule.Quick32Crc(crcdata, length + 3, crc);
//        //QuickCrc32(crcdata, length + 3, crc);
//
//        System.arraycopy(crc, 0, sendBuffer, length + 4, 4);
//
//        //java.util.zip.CRC32();
//        financialModule.write(sendBuffer);
//
//        return 0;
//    }

//    public int recvPacket(byte[] pbyRecvData, short[] pwPacketetLen, int dwTimeoutMs) throws IOException {
//        int byRet = 0;
//        byte[] abyCrc32 = new byte[4];
//        int i;
//        byte[] ch = new byte[1];
//        short wPacketLen = 0;
//        int dwBegintick, dwCurtick;
//
//        Log.d("", "begin");
//        for (i = 0; i < dwTimeoutMs; i += 1000) {
//
//            byRet = financialModule.read(ch, 1, 1000);
//
//            if ((0 == byRet) && (0x02 == ch[0])) {
//                pbyRecvData[0] = ch[0];
//                break;
//            }
//            try {
//                Thread.sleep(50);//延时50ms
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }
//        if (i >= dwTimeoutMs) {
//            Log.d("", "timeout");
//            return 104;
//
//        }
//        for (i = 1; i < 4; i++) {
//
//            byRet = financialModule.read(ch, 1, 1000); // timeout = 100ms
//
//            if (0 != byRet) {
//                return 101;
//            }
//            pbyRecvData[i] = ch[0];
//        }
//        wPacketLen = (short) (pbyRecvData[2] * 256 + pbyRecvData[3]);
//        pwPacketetLen[0] = (short) (wPacketLen + 8);
//        if (wPacketLen > 520) {
//            return 103;
//        }
//        for (i = 4; i < wPacketLen + 8; i++) {
//
//            byRet = financialModule.read(ch, 1, 1000);
//
//            if (0 != byRet) {
//                return 101;
//            }
//            pbyRecvData[i] = ch[0];
//        }
//        Log.i("RecvPacket", "" + ByteTool.bytearrayToHexString(pbyRecvData, wPacketLen + 8));
//
//        return 0;
//    }

    protected static void deliverResult(final DeviceCallback callback, DeviceInterface.Result result, Bundle bundle, boolean onMainThread) {

        DeviceInterface.deliverResult(callback, result, bundle, onMainThread);

    }




}
